#define DrawBaseProp 
// #define YF_POST_PROCESSING


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEditor;
#if YF_POST_PROCESSING
using YF.Art.PostProcessing;
#endif

namespace DT.Art.VFX.DTEditorGUI
{
    using pKey = DTPropKeyName;
    using fkey = DTFilteKeyName;


    /// <summary>
    /// The base class for shader GUI in URP.
    /// </summary>
    public partial class BaseShaderGUI : ShaderGUI
    {

        MaterialProperty VfxModeProp;
        public BaseShaderGUI()
        {
            ExpandBit.DTAddKey("Options", true);
            m_Module.Clear();
            // m_Module.Add(ModuleType.None, new DT_Module(ModuleType.None.ToString(), disN: ("", "", "", ""), fbtn: 4, isv: false, isE: false)); //示例
            m_Module.Add(ModuleKey.YFPost, new DT_Module(ModuleKey.YFPost.ToString(), disN: ("YF POST PROCESSING", "YF 后效功能", "", "YF"), fbtn: 0, isv: false, isE: false));
            m_Module.Add(ModuleKey.MainTex, new DT_Module(ModuleKey.MainTex.ToString(), disN: ("Main Tex", "Main Tex (主纹理)", "", "主"), fbtn: 4, isv: true, isE: true));

            m_Module.Add(ModuleKey.ColorTex, new DT_Module(ModuleKey.ColorTex.ToString(), disN: ("Color Tex II", "Color Tex (向前新加一层颜色贴图)", "", "副"), fbtn: 4, isv: false, isE: false));
            m_Module.Add(ModuleKey.MaskTex, new DT_Module(ModuleKey.MaskTex.ToString(), disN: ("Mask Mode", "Mask (遮罩)", "", "遮"), fbtn: 4, isv: false, isE: false));
            m_Module.Add(ModuleKey.DistortTex, new DT_Module(ModuleKey.DistortTex.ToString(), disN: ("Distort Mode", "Distort Mode (扰动UV)", "", "扰"), fbtn: 4, isv: false, isE: false));
            m_Module.Add(ModuleKey.DissolveTex, new DT_Module(ModuleKey.DissolveTex.ToString(), disN: ("Dissolve Mode", "Dissolve Mode (溶解)", "", "溶"), fbtn: 4, isv: false, isE: false));
            m_Module.Add(ModuleKey.FNLMode, new DT_Module(ModuleKey.FNLMode.ToString(), disN: ("FNL Mode", "FNL Mode (菲尼尔)", "", "菲"), fbtn: 0, isv: false, isE: false));
            m_Module.Add(ModuleKey.GroundClipMode, new DT_Module(ModuleKey.GroundClipMode.ToString(), disN: ("Ground Clip Mode", "Ground Clip (地面裁剪)", "", "地"), fbtn: 0, isv: false, isE: false));

            m_Module.Add(ModuleKey.HelpInfo, new DT_Module(ModuleKey.HelpInfo.ToString(), disN: ("Help Info", "Help Info (帮助信息)", "", "帮"), fbtn: 1, isv: false, isE: false));
            ModuleInit();
            if (m_Module.Count > 14)
            {
                throw new Exception("m_Module.Count > 14");
            }


        }

        #region  OnGUI
        public override void OnGUI(MaterialEditor materialEditorIn, MaterialProperty[] properties)
        {
            if (materialEditorIn == null)
            {
                return;
                // throw new ArgumentNullException("materialEditorIn");
            }
            this.materialEditor = materialEditorIn;
            Material _material = this.materialEditor.target as Material;
            this.material = _material;
            if (this.material == null)
            {
                return;
                // throw new ArgumentNullException("material");
            }
            VfxModeProp = DTFindProperty(DTVfxBaseProperty.m_ModuleKey, properties);
            DrawPPModuleInit(properties);
            DTdefGUIColor = GUI.color;
            DTdefBackColor = GUI.backgroundColor;
            DTdefLableWidth = EditorGUIUtility.labelWidth;
            DTdeficonsize = EditorGUIUtility.GetIconSize();
            EditorGUIUtility.SetIconSize(new Vector2(16, 16));
            if (this.isDebug)
            {
                this.isDebug = m_Module[ModuleKey.HelpInfo].IsEnable ? (m_Module[ModuleKey.HelpInfo].IsViewnFoldout ? this.isDebug : false) : false;
            }
            EditorGUILayout.Space(3);
            DrawOptions(materialEditor, properties);
            m_Module[ModuleKey.MainTex].IsEnable = true;
            MaterialProperty modulesw = FindProperty(DTVfxBaseProperty.m_ModuleKey, properties);
            Vector4 modulsw = modulesw.vectorValue;
            int viewsw = (int)modulsw.y;
            int enablsw = (int)modulsw.x;
            foreach (var item in m_Module)
            {
                // ExpandBit.DTAddKey(item.Key.ToString());
                item.Value.IsViewnFoldout = (viewsw >> (int)item.Value.bitIndex & 0x1) > 0;
                if (!item.Value.IsEnable || item.Value.DrawGUI == null)
                {
                    // item.Value.IsViewnFoldout = false;
                    // ExpandBit[item.Key.ToString()] = false;
                    continue;
                }

                if (item.Value.DrawGUI != null)
                {

                    item.Value.Draw(materialEditor, properties);
                    GUI.enabled = true;
                    viewsw = DTUtil.ReplaceBits((item.Value.IsViewnFoldout ? 1 : 0), viewsw, (int)item.Value.bitIndex, 1);
                }
            }
            modulsw.y = viewsw;
            modulesw.vectorValue = modulsw;
            DrawLastOptions(materialEditor, properties);
            var rect = EditorGUILayout.GetControlRect(true, 30);
            rect.xMin = 4;
            if (GUI.Button(rect, "清理材质球"))
            {
                _material.ClearMaterial();
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();
            }
            //=======================================================================================================================================
#if DrawBaseProp
            const string BasekeyTemp = "Base Prop";
            ExpandBit.DTAddKey(BasekeyTemp);
            using (var header = new DT_HeaderScope("Base Prop", ExpandBit["Base Prop"], materialEditor))
            {
                if (header.expanded)
                {
                    base.OnGUI(materialEditor, properties);
                }
                ExpandBit["Base Prop"] = header.expanded;
            }
#endif
            EditorGUIUtility.SetIconSize(DTdeficonsize);
            //=======================================================================================================================================
        }
        #endregion

        #region DrawMainTex

        protected virtual void DrawMainTex(DT_HeaderScope header, MaterialEditor materialEditor, MaterialProperty[] properties)
        {
            DTGUIBitDate GUIDate = new DTGUIBitDate("MainTex", "Main Tex (主纹理)");
            GUIDate.Propertykeys[pKey.enable] = null;
            GUIDate.Propertykeys[pKey.tex] = DTFindProperty("_MainTex", properties);
            GUIDate.Propertykeys[pKey.texColor] = DTFindProperty("_MainColor", properties);
            GUIDate.Propertykeys[pKey.texST] = DTFindProperty("_MainTex", properties);
            GUIDate.Propertykeys[pKey.texST1] = null;
            GUIDate.Propertykeys[pKey.texST2] = null;

            GUIDate.Propertykeys[pKey.uspeed] = DTFindProperty("_MainUValue", properties);
            GUIDate.Propertykeys[pKey.vspeed] = DTFindProperty("_MainVValue", properties);
            GUIDate.Propertykeys[pKey.matrix0] = DTFindProperty("_MainMatrix0", properties);
            GUIDate.Propertykeys[pKey.matrix1] = DTFindProperty("_MainMatrix1", properties);
            GUIDate.Propertykeys[pKey.ToolgetSw] = DTFindProperty("_MainSW", properties);

            GUIDate.Propertykeys[pKey.brightness] = DTFindProperty("_MainBrightness", properties);
            GUIDate.Propertykeys[pKey.alpha] = DTFindProperty("_MainAlpha", properties);

            GUIDate.Propertykeys[pKey.filterValue4] = DTFindProperty("_MainFilterValue4", properties);


            GUIDate.SetBitProp(fkey.Umode, pKey.ToolgetSw, 0, 4, ChannelMode.x);
            GUIDate.SetBitProp(fkey.Vmode, pKey.ToolgetSw, 4, 4, ChannelMode.x);

            GUIDate.SetBitProp(fkey.Screen, pKey.ToolgetSw, 0, 1, ChannelMode.y);
            GUIDate.SetBitProp(fkey.Polar, pKey.ToolgetSw, 1, 1, ChannelMode.y);
            GUIDate.SetBitProp(fkey.Cx, pKey.ToolgetSw, 2, 1, ChannelMode.y);
            GUIDate.SetBitProp(fkey.Cy, pKey.ToolgetSw, 3, 1, ChannelMode.y);
            GUIDate.SetBitProp(fkey.Fx, pKey.ToolgetSw, 4, 1, ChannelMode.y);
            GUIDate.SetBitProp(fkey.Fy, pKey.ToolgetSw, 5, 1, ChannelMode.y);
            GUIDate.SetBitProp(fkey.Fill, pKey.ToolgetSw, 6, 1, ChannelMode.y);

            GUIDate.SetBitProp(fkey.Distort, pKey.ToolgetSw, 13, 1, ChannelMode.y);
            GUIDate.SetBitProp(fkey.Frame, pKey.ToolgetSw, 14, 1, ChannelMode.y);



            //--------
            GUIDate.UVBTNS = new List<string>()
            {
                fkey.Screen,fkey.Polar,fkey.Cx,fkey.Cy,fkey.Fx,fkey.Fy,fkey.Fill,fkey.Distort,fkey.Frame
            };
            GUIDate.InitProperty();
            if (GUIDate.GetProp(pKey.tex) == null || GUIDate.GetProp(pKey.ToolgetSw) == null)
            {
                return;
            }
            GUIDate.MEBeginProperty();
            DrawTexUV(header, materialEditor, properties, GUIDate);
            GUIDate.IsCAddFilter = false;
            if (header.expanded && GUIDate.IsCAddFilter)
            {
                EditorGUI.indentLevel++;
                EditorGUILayout.BeginVertical(EditorStyles.helpBox);
                EditorGUI.indentLevel++;
                EditorGUILayout.HelpBox("Main Tex (主纹理)", MessageType.None);
                DTGUIEx.DrawLine(2);
                EditorGUILayout.HelpBox("Main Tex (主纹理)", MessageType.None);
                EditorGUILayout.HelpBox("Main Tex (主纹理)", MessageType.None);

                EditorGUI.indentLevel--;
                EditorGUILayout.EndVertical();
                EditorGUI.indentLevel--;
            }
            GUIDate.MEEndProperty();
        }
        #endregion
    }

    public partial class BaseShaderGUI
    {
        protected MaterialEditor materialEditor { get; set; }
        protected Material material { get; set; }
        public Dictionary<string, bool> ExpandBit = new Dictionary<string, bool>();


        protected Dictionary<ModuleKey, DT_Module> m_Module = new Dictionary<ModuleKey, DT_Module>();
        protected bool isDebug = false;
        protected Color DTdefGUIColor = Color.white;
        protected Color DTdefBackColor = Color.white;
        protected float DTdefLableWidth = -1;
        protected Vector2 DTdeficonsize = Vector2.zero;
        protected virtual GUIContent[] uvmodeArray => new GUIContent[]
        {
            DTGUIEx.DTGetContent("Animation Value"),
            DTGUIEx.DTGetContent("Auto Speed"),
            DTGUIEx.DTGetContent("Particle Custom1.X"),
            DTGUIEx.DTGetContent("Particle Custom1.Y"),
            DTGUIEx.DTGetContent("Particle Custom1.Z"),
            DTGUIEx.DTGetContent("Particle Custom1.W"),
            DTGUIEx.DTGetContent("Particle Custom2.X"),
            DTGUIEx.DTGetContent("Particle Custom2.Y"),
            DTGUIEx.DTGetContent("Particle Custom2.Z"),
            DTGUIEx.DTGetContent("Particle Custom2.W"),
            DTGUIEx.DTGetContent("Particle Color.a")
        };


        protected virtual void ModuleInit()
        {
            m_Module[ModuleKey.MainTex].DrawGUI = DrawMainTex;
            m_Module[ModuleKey.HelpInfo].DrawGUI = DrawHelpInfo;
#if YF_POST_PROCESSING
            m_Module[ModuleType.YFPost].DrawGUI = DrawCustomPostProcessing;
            m_Module[ModuleType.YFPost].ToolTip = "YF 后效功能";
            m_Module[ModuleType.YFPost].IconName = ""; 
            // ExpandBit.DTAddKey(ModuleKey.YFPost.ToString(), true);
#endif
            // ExpandBit.DTAddKey(ModuleKey.MainTex.ToString(), true);
            // ExpandBit.DTAddKey(ModuleKey.HelpInfo.ToString(), true);
            // ExpandBit.DTAddKey(ModuleKey.DistortTex.ToString(), false);
            // ExpandBit.DTAddKey(ModuleKey.DissolveTex.ToString(), false);

            // ExpandBit.DTAddKey(ModuleKey.FNLMode.ToString(), false);
            // ExpandBit.DTAddKey(ModuleKey.GroundClipMode.ToString(), false);

            // const string BasekeyTemp = "Base Prop";
            // ExpandBit.DTAddKey(BasekeyTemp);
        }

        protected virtual void DrawPPModuleInit(MaterialProperty[] properties)
        {
#if YF_POST_PROCESSING
              DTFindProperty("_FYFPOSTEnabled", properties).floatValue = m_Module[ModuleKey.YFPost].IsEnable? 1 : 0;
#endif 
        }


        #region Base Draw GUI
        protected virtual void DrawTexUV(DT_HeaderScope header, MaterialEditor materialEditor, MaterialProperty[] properties, DTGUIBitDate GUIDate)
        {
            //----------------
            // GUIData.MEBeginProperty();
            //----------------
            string Selfmodkey = GUIDate.Funkey + "UVFilter";
            string Colormodkey = GUIDate.Funkey + "ColorFilter";
            string frameKey = GUIDate.Funkey + "UVFramemodekey";
            string filterkey = GUIDate.Funkey + "UVFilterodekey";

            ExpandBit.DTAddKey(Selfmodkey);
            ExpandBit.DTAddKey(Colormodkey);
            ExpandBit.DTAddKey(filterkey);
            ExpandBit.DTAddKey(frameKey);

            GUIDate.SetBitView(fkey.Distort, m_Module[ModuleKey.DistortTex].DrawGUI != null && m_Module[ModuleKey.DistortTex].IsEnable);
            //----------------  
            int indent = EditorGUI.indentLevel;
            EditorGUI.indentLevel = 0;
            var btn1Rect = header.BtnRect;
            if (header.expanded)
            {
                //----------------
                EditorGUILayout.BeginHorizontal();
                {
                    materialEditor.TexturePropertySingleLine(new GUIContent(GUIDate.DisplayName), GUIDate.GetProp(pKey.tex));
                    EditorGUILayout.BeginVertical();
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.Space(0, true);
                    foreach (var item in GUIDate.UVBTNS)
                    {
                        if (item == fkey.Enter)
                        {
                            EditorGUILayout.EndHorizontal();
                            EditorGUILayout.BeginHorizontal();
                            EditorGUILayout.Space(0, true);
                            continue;
                        }
                        Bitkey tmp = GUIDate.GetBitkey(item);
                        if (!tmp.isView)
                        {
                            GUIDate.bitkeys[item].SetValue(GUIDate.Propertykeys, 0);
                            continue;
                        }
                        Action<int> btncallback = null;
                        if (item == fkey.Fx)
                        {
                            btncallback = (val) =>
                            {
                                DTchannelDate v = GUIDate.GetProp(pKey.tex).GetValue();
                                v.x = Mathf.Abs(v.x) * (val > 0 ? -1 : 1);
                                GUIDate.GetProp(pKey.tex).SetValue(v);
                            };
                        }
                        if (item == fkey.Fy)
                        {
                            btncallback = (val) =>
                            {
                                DTchannelDate v = GUIDate.GetProp(pKey.tex).GetValue();
                                v.y = Mathf.Abs(v.y) * (val > 0 ? -1 : 1);
                                GUIDate.GetProp(pKey.tex).SetValue(v);
                            };
                        }
                        DTGUIEx.ToggleBTNShaderProperty(materialEditor, GUIDate.GetProp(item), tmp.lable, tmp.mode, tmp.index, tmp.len, callback: btncallback);
                    }
                    // EditorGUILayout.Space(3, false);
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.EndVertical();
                }
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.Space(3, false);
                //----------------   
                EditorGUI.indentLevel++;
                GUILayout.BeginVertical(EditorStyles.helpBox);
                //----------------                    
                DTGUIEx.DrawVector2FieldTex(materialEditor, GUIDate.GetProp(pKey.texST), DTGUIEx.DTGetContent("Tiling"), ChannelMode.x | ChannelMode.y,
                    callback: (val) =>
                    {
                        GUIDate.bitkeys[fkey.Fx].SetValue(GUIDate.Propertykeys, val.x >= 0 ? 0 : 1);
                        GUIDate.bitkeys[fkey.Fy].SetValue(GUIDate.Propertykeys, val.y >= 0 ? 0 : 1);
                    });
                DTGUIEx.DrawVector2FieldTex(materialEditor, GUIDate.GetProp(pKey.texST), DTGUIEx.DTGetContent("Offset"), ChannelMode.z | ChannelMode.w);
                DTGUIEx.DrawFloatField(materialEditor, GUIDate.GetProp(pKey.matrix0), DTGUIEx.DTGetContent("Rotation"), ChannelMode.w);
                //---------------- 

                //---------------- 
                DTGUIEx.DrawLine(3);
                Bitkey ud = GUIDate.GetBitkey(fkey.Umode);
                Bitkey vd = GUIDate.GetBitkey(fkey.Vmode);
                // EditorGUI.indentLevel++;
                EditorGUILayout.BeginHorizontal();
                if (GUIDate.GetUVModeKey(fkey.Umode) >= uvmodeArray.Length)
                {
                    throw new Exception("GetUVModeKey(\"Umode\") >= uvmodeArray.Length");
                }
                switch (GUIDate.GetUVModeKey(fkey.Umode))
                {
                    case 0:
                        DTGUIEx.DrawFloatField(materialEditor, GUIDate.GetProp(pKey.uspeed), DTGUIEx.DTGetAnimContent(GUIDate.GetProp(pKey.uspeed).name));
                        break;
                    case 1:
                        DTGUIEx.DrawFloatField(materialEditor, GUIDate.GetProp(pKey.filterValue4), DTGUIEx.DTGetContent("U Flow Speed"), ChannelMode.x);
                        break;
                    default:
                        DTGUIEx.DrawPopupField(materialEditor, GUIDate.GetProp(fkey.Umode), new GUIContent("U Flow Custom"), uvmodeArray, channleIndex: ud.mode, index: ud.index, len: ud.len);
                        break;
                }
                if (GUIDate.GetUVModeKey(fkey.Umode) < 2)
                {
                    DTGUIEx.DrawPopupField(materialEditor, GUIDate.GetProp(fkey.Umode), GUIContent.none, uvmodeArray, width: 20, channleIndex: ud.mode, index: ud.index, len: ud.len, isEd: true);
                }

                EditorGUILayout.EndHorizontal();
                EditorGUILayout.BeginHorizontal();
                if (GUIDate.GetUVModeKey(fkey.Vmode) >= uvmodeArray.Length)
                {
                    throw new Exception("GetUVModeKey(\"Vmode\") >= uvmodeArray.Length");
                }
                switch (GUIDate.GetUVModeKey(fkey.Vmode))
                {
                    case 0:
                        DTGUIEx.DrawFloatField(materialEditor, GUIDate.GetProp(pKey.vspeed), DTGUIEx.DTGetAnimContent(GUIDate.GetProp(pKey.vspeed).name));
                        break;
                    case 1:
                        DTGUIEx.DrawFloatField(materialEditor, GUIDate.GetProp(pKey.filterValue4), DTGUIEx.DTGetContent("V Flow Speed"), ChannelMode.y);
                        break;
                    default:
                        DTGUIEx.DrawPopupField(materialEditor, GUIDate.GetProp(fkey.Vmode), new GUIContent("V Flow Custom"), uvmodeArray, channleIndex: vd.mode, index: vd.index, len: vd.len);
                        break;
                }
                if (GUIDate.GetUVModeKey(fkey.Vmode) < 2)
                {
                    DTGUIEx.DrawPopupField(materialEditor, GUIDate.GetProp(fkey.Vmode), GUIContent.none, uvmodeArray, width: 20, channleIndex: vd.mode, index: vd.index, len: vd.len, isEd: true);
                }
                GUI.enabled = true;
                EditorGUILayout.EndHorizontal();
                if (GUIDate.GetBTNout(fkey.Distort))
                {
                    DTGUIEx.DrawLine(3);
                    DTGUIEx.DrawVector2Field(materialEditor, GUIDate.GetProp(pKey.filterValue4), DTGUIEx.DTGetContent("Distort Intensity"), ChannelMode.z | ChannelMode.w);
                }
                if (GUIDate.GetProp(pKey.texColor) != null || GUIDate.GetProp(pKey.brightness) != null || GUIDate.GetProp(pKey.alpha) != null)
                {
                    DTGUIEx.DrawLine(3);
                    // TexColor
                    DTGUIEx.DrawColorField(materialEditor, GUIDate.GetProp(pKey.texColor), DTGUIEx.DTGetAnimContent(GUIDate.GetPropName(pKey.texColor)));
                    //Brightness
                    DTGUIEx.DrawFloatField(materialEditor, GUIDate.GetProp(pKey.brightness), DTGUIEx.DTGetAnimContent(GUIDate.GetPropName(pKey.brightness)), 0f, false);
                    //Alpha
                    // if (GUIData.GetProp(pKey.texColor) != null)
                    DTGUIEx.DrawFloatField(materialEditor, GUIDate.GetProp(pKey.alpha), DTGUIEx.DTGetAnimContent(GUIDate.GetPropName(pKey.alpha)), 0f, 1f);
                }

                // EditorGUILayout.Space(1, false);

                EditorGUI.indentLevel--;
                // }
                //---------------- 
                if (GUIDate.GetBTNout(fkey.Frame))
                {
                    ExpandBit[frameKey] = DTGUIEx.DrawFoldout(DTGUIEx.DTGetContent("Frame Filter [开发中...]"), ExpandBit[frameKey], true);
                    if (ExpandBit[frameKey])
                    {
                        EditorGUI.indentLevel++;
                        GUI.enabled = false;
                        EditorGUILayout.Vector2Field(DTGUIEx.DTGetContent("Tiles"), Vector2.zero);
                        EditorGUILayout.Vector2Field(DTGUIEx.DTGetContent("Start/End Frame"), Vector2.up);
                        EditorGUILayout.IntField(DTGUIEx.DTGetContent("Cycles", "loop: -1,count:>0"), -1);
                        EditorGUILayout.FloatField(DTGUIEx.DTGetContent("Time Value"), 0);
                        GUI.enabled = true;
                        EditorGUI.indentLevel--;
                    }
                }
                EditorGUILayout.Space(2, false);
                GUILayout.EndVertical();
                EditorGUI.indentLevel--;
            }
            else
            {

                btn1Rect.width = 40;
                btn1Rect.y += 1.5f;
                materialEditor.TexturePropertyMiniThumbnail(btn1Rect, GUIDate.GetProp(pKey.tex), "", "");
                btn1Rect.y -= 1.5f;
            }
            btn1Rect.x += 40; //btn1Rect.width;
            btn1Rect.width = 20;
            DoTexWarringBtn(materialEditor, btn1Rect, GUIDate.GetProp(pKey.tex));
            EditorGUI.indentLevel = indent;
            //----------------
            SetUVMate(GUIDate);
            //----------------
            // GUIData.MEEndProperty();
        }
        #endregion //Base Draw GUI

        #region 次级界面
        protected virtual void DrawSendTex(MaterialEditor materialEditor, MaterialProperty[] properties)
        {

        }
        #endregion

        #region Help
        /// <summary>
        ///  1. 这是一个帮助信息
        ///  2. 这是一个帮助信息
        ///  3. 这是一个帮助信息
        /// </summary>
        protected virtual string HelpInfo => @"
  1. 这是一个帮助信息
  2. 这是一个帮助信息
  3. 这是一个帮助信息";
        #endregion

        #region DrawLocalGlobal 
        public virtual void DrawLocalGlobal(MaterialEditor materialEditor, MaterialProperty[] properties)
        {

            DTGUIBitDate GUIDate = new DTGUIBitDate("Global Properties", "Global Properties");

            // GUIDate.SetBitProp(fkey.ColorBlend, pKey.ToolgetSw, 0, 4, ChannelMode.z);
            // GUIDate.SetBitProp(fkey.AlphaBlend, pKey.ToolgetSw, 4, 4, ChannelMode.z);
            // GUIDate.SetBitProp(fkey.OnlyChannleAlp, pKey.ToolgetSw, 8, 4, ChannelMode.z);

            // GUIDate.SetBitProp(fkey.Invert, pKey.ToolgetSw, 12, 1, ChannelMode.z);
            // GUIDate.SetBitProp(fkey.Gray, pKey.ToolgetSw, 13, 1, ChannelMode.z);

            const string globalAlpha = nameof(globalAlpha);
            GUIDate.Propertykeys = new Dictionary<string, MaterialProperty>();


            GUIDate.Propertykeys[globalAlpha] = DTFindProperty(DTVfxBaseProperty.GlobalAlpha, properties);
            GUIDate.InitProperty();
            int indent = EditorGUI.indentLevel;

            EditorGUI.indentLevel = 0;
            ExpandBit.DTAddKey(GUIDate.Funkey);

            GUIDate.MEBeginProperty();
            ExpandBit[GUIDate.Funkey] = DTGUIEx.DrawFoldout(DTGUIEx.DTGetContent(GUIDate.DisplayName, icon: ""), ExpandBit[GUIDate.Funkey], true);
            if (ExpandBit[GUIDate.Funkey])
            {
                EditorGUI.indentLevel++;
                materialEditor.DrawRangeField(GUIDate.GetProp(globalAlpha), DTGUIEx.DTGetAnimContent(GUIDate.GetPropName(globalAlpha)));

                EditorGUILayout.Slider(DTGUIEx.DTGetAnimContent("Gray"), 0f, 0f, 1f);
                EditorGUILayout.Slider(DTGUIEx.DTGetAnimContent("Inver"), 0f, 0f, 1f);

                EditorGUI.indentLevel--;
            }
            GUIDate.MEEndProperty();

            EditorGUI.indentLevel = indent;
        }
        #endregion





        #region DrawHelpInfo
        protected virtual void DrawHelpInfo(DT_HeaderScope header, MaterialEditor materialEditor, MaterialProperty[] properties)
        {
            var btn1Rect = header.BtnRect;
            if (header.expanded)
            {
                EditorGUILayout.HelpBox($@"Help Info:{HelpInfo}", MessageType.Info, true);
                btn1Rect.width = 20; btn1Rect.x -= 5f;
                btn1Rect.y += 1.2f;
                GUIStyle style = new GUIStyle(EditorStyles.iconButton)
                {
                    imagePosition = ImagePosition.ImageOnly,
                    alignment = TextAnchor.MiddleCenter,
                    fixedHeight = 18,
                    fixedWidth = 18,
                    padding = new RectOffset(1, 1, 1, 1)
                };
                if (GUI.Button(btn1Rect, DTGUIEx.DTGetContent(icon: this.isDebug ? "d_MoreOptions" : "Pre toolbar act overlay"), style))
                {
                    this.isDebug = !this.isDebug;
                }
            }
        }
        #endregion
        #region DrawCustomPostProcessing
#if YF_POST_PROCESSING
        protected void DrawCustomPostProcessing(DT_HeaderScope header, MaterialEditor materialEditor, MaterialProperty[] properties)
        {
            if (header.expanded)
            {
                EditorGUILayout.HelpBox(@$"YF PostProcessing 未加载相关模块。", MessageType.Warning, true);

            }
        }
#endif
        #endregion
        #region DrawOptions
        /// <summary>
        /// Draws the options section of the shader.
        /// </summary>
        protected virtual void DrawOptions(MaterialEditor materialEditor, MaterialProperty[] properties)
        {

            MaterialProperty blendModeProp = DTFindProperty(DTVfxBaseProperty.BlendMode, properties);
            MaterialProperty cullingProp = DTFindProperty(DTVfxBaseProperty.CullMode, properties);
            MaterialProperty zTestProp = DTFindProperty(DTVfxBaseProperty.ZTest, properties);
            MaterialProperty alphaToMaskProp = DTFindProperty(DTVfxBaseProperty.AlphaToMask, properties);
            MaterialProperty colormask = DTFindProperty(DTVfxBaseProperty.ColorMask, properties);

            MaterialProperty stencilCompProp = DTFindProperty("_StencilComp", properties);
            MaterialProperty stencilProp = DTFindProperty("_Stencil", properties);
            MaterialProperty stencilOpProp = DTFindProperty("_StencilOp", properties);
            MaterialProperty stencilWriteMaskProp = DTFindProperty("_StencilWriteMask", properties);
            MaterialProperty stencilReadMaskProp = DTFindProperty("_StencilReadMask", properties);
            MaterialProperty zWriteProp = DTFindProperty("_ZWrite", properties);

            const string key = "Options";
            ExpandBit.DTAddKey(key);

            const string colormaskEditor = "Color Mask Editor";
            ExpandBit.DTAddKey(colormaskEditor);
            UpdateModule(VfxModeProp);
            using (var header = new DT_HeaderScope(DTGUIEx.DTGetContent(key), ExpandBit[key], materialEditor))
            {
                if (header.expanded)
                {
                    materialEditor.DrawPopupField(blendModeProp, new GUIContent("Blending Mode"), new string[] { "Alpha", "Premultiply", "Additive", "Multiply" });
                    materialEditor.DrawPopupField(cullingProp, new GUIContent("Render Face"), new string[] { "Both", "Back", "Front" });
                    materialEditor.DrawPopupField(zTestProp, new GUIContent("Render ZTest"), new string[] { "Normal", "AlwaysTop" },
                            args: new DECodeArgs<int>() { OutDeCode = (a) => { return a * 4 + 4; }, InDeCode = (a) => { return a / 4 - 1; } });
                    //Color Mask
                    {
                        string colormaskiconname = ExpandBit[colormaskEditor] ? "IN LockButton" : "IN LockButton On";
                        GUI.enabled = ExpandBit[colormaskEditor];
                        EditorGUI.indentLevel += 1;
                        materialEditor.DrawEnumFlagsField<dtColorMask>(colormask, DTGUIEx.DTGetContent("Color Mask"),
                                args: new DECodeArgs<int>() { InDeCode = (a) => { return (a == 15) ? -1 : a; }, OutDeCode = (a) => { return a & 0xf; } });
                        EditorGUI.indentLevel -= 1;
                        GUI.enabled = true;
                        Rect btnr = GUILayoutUtility.GetLastRect();
                        btnr.width = 16; btnr.y += 1f;
                        if (!EditorGUIUtility.isProSkin)
                        {
                            GUI.color = new Color(0.5f, 0.5f, 0.5f, 1f);
                        }
                        if (GUI.Button(btnr, DTGUIEx.DTGetContent(icon: colormaskiconname), new GUIStyle(EditorStyles.iconButton)
                        {
                            imagePosition = ImagePosition.ImageOnly,
                            padding = new RectOffset(0, 0, 0, 0)
                        }))
                        {
                            ExpandBit[colormaskEditor] = !ExpandBit[colormaskEditor];
                        }
                        GUI.color = DTdefGUIColor;
                    }
                    bool allviewkey = ((int)VfxModeProp.vectorValue.y & 0x7fff) > 0;
                    GUIContent UseModeLable = DTGUIEx.DTGetContent("Select Module", "Tips:\n  模组的选择是功能的开关,并非单纯的界面显示开关.", "");
                    string allviewiconname = allviewkey ? "animationvisibilitytoggleon" : "scenevis_hidden_hover";
                    if (EditorGUIUtility.isProSkin)
                    {
                        allviewiconname = allviewkey ? "d_animationvisibilitytoggleon" : "d_scenevis_hidden_hover";
                    }
                    GUIContent viewbtn = DTGUIEx.DTGetContent("", tooltip: "页签显示的总控制.", icon: allviewiconname);

                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.PrefixLabel(UseModeLable);
                    EditorGUILayout.Space(0, true);
                    if (materialEditor.DrawIconButton(viewbtn))
                    {
                        Vector4 tmp = VfxModeProp.vectorValue;
                        allviewkey = !allviewkey;
                        if (allviewkey)
                        {
                            tmp.y = (int)tmp.y | 0x7fff;
                        }
                        else
                        {
                            tmp.y = 0;
                        }
                        VfxModeProp.vectorValue = tmp;
                    }
                    foreach (var item in m_Module)
                    {
                        if (item.Value.DrawGUI == null) continue;
                        GUIContent lable = DTGUIEx.DTGetContent(item.Value.BtnDisplayName, item.Value.ToolTip);
                        materialEditor.ToggleBTNShaderProperty(VfxModeProp, lable, channleIndex: ChannelMode.x, index: item.Value.bitIndex, len: 1);
                    }
                    EditorGUILayout.Space(3, false);
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.Space(2, false);

                    //---------------------------
                    // Debug view
                    //---------------------------
                    GUI.enabled = this.isDebug;
                    if (this.isDebug)
                    {
                        EditorGUILayout.Space();
                        GUI.backgroundColor = new Color(0.6f, 0.2f, 0.2f, 1.0f);
                        EditorGUILayout.LabelField("Debug Mode:", new GUIStyle(EditorStyles.label) { fontStyle = FontStyle.Bold, fontSize = 15 });
                    }
                    GUI.backgroundColor = DTdefBackColor;
                    if (this.isDebug)
                    {
                        GUI.backgroundColor = new Color(0.6f, 0.2f, 0.2f, 1.0f);
                        EditorGUILayout.BeginVertical("box");
                        DTGUIEx.DrawPopupField(materialEditor, alphaToMaskProp, new GUIContent("Alpha To Mask:"), new string[] { "Off", "On" });
                        DTGUIEx.DrawPopupField(materialEditor, zWriteProp, new GUIContent("Z Write:"), new string[] { "Off", "On" });
                        materialEditor.DrawFloatField(stencilCompProp, new GUIContent("Stencil Comp:"));
                        materialEditor.DrawFloatField(stencilProp, new GUIContent("Stencil:"));
                        materialEditor.DrawFloatField(stencilOpProp, new GUIContent("Stencil Op:"));
                        materialEditor.DrawFloatField(stencilWriteMaskProp, new GUIContent("Stencil Write Mask:"));
                        materialEditor.DrawFloatField(stencilReadMaskProp, new GUIContent("Stencil Read Mask:"));
                        if (GUILayout.Button("Reset"))
                        {
                            if (alphaToMaskProp != null)
                                alphaToMaskProp.floatValue = 0;
                            if (zWriteProp != null)
                                zWriteProp.floatValue = 0;
                            if (stencilCompProp != null)
                                stencilCompProp.floatValue = 8;
                            if (stencilProp != null)
                                stencilProp.floatValue = 0;
                            if (stencilOpProp != null)
                                stencilOpProp.floatValue = 0;
                            if (stencilWriteMaskProp != null)
                                stencilWriteMaskProp.floatValue = 255;
                            if (stencilReadMaskProp != null)
                                stencilReadMaskProp.floatValue = 255;
                        }
                        EditorGUILayout.EndVertical();
                        EditorGUILayout.Space();
                        GUI.backgroundColor = DTdefBackColor;
                    }
                    GUI.enabled = true;
                    DrawLocalGlobal(materialEditor, properties);
                    //执行面板设置后的结果  
                    SetBlend();

                }
                ExpandBit[key] = header.expanded;
            }
        }
        #endregion
        #region DrawLastOptions
        /// <summary>
        /// Draws the last options section of the shader.
        /// </summary>
        protected void DrawLastOptions(MaterialEditor materialEditor, MaterialProperty[] properties)
        {
            var rect = GUILayoutUtility.GetRect(1, 1);
            rect.xMin = 0;
            EditorGUI.DrawRect(rect, new Color(0, 0, 0, 0.2f));
            EditorGUI.BeginChangeCheck();
            {
                MaterialProperty[] _props = { };
                base.OnGUI(materialEditor, _props);
            }
        }
        #endregion
        #region Others
        protected virtual void UpdateModule(MaterialProperty prop)
        {
            Vector4 v = prop.vectorValue;
            v.x = ((int)v.x) | (1 << (int)ModuleKey.MainTex);
            v.x = ((int)v.x) | (1 << (int)ModuleKey.YFPost);
            foreach (var item in m_Module)
            {
                if (item.Value.DrawGUI == null) continue;
                item.Value.IsEnable = ((int)v.x >> item.Value.bitIndex & 0x1) != 0;
                item.Value.IsViewnFoldout = ((int)v.y >> item.Value.bitIndex & 0x1) != 0;
            }
            prop.vectorValue = v;
        }
        public MaterialProperty DTFindProperty(string name, MaterialProperty[] properties)
        {
            return FindProperty(name, properties, false);
        }

        protected Rect DoTexWarringBtn(MaterialEditor materialEditor, Rect btnRect, params MaterialProperty[] property)
        {
            if (property == null)
            {
                return btnRect;
            }
            (int, int, string, string) ret = materialEditor.CheckTexsError(property);
            GUIStyle style = new GUIStyle(EditorStyles.iconButton)
            {
                imagePosition = ImagePosition.ImageOnly,
                alignment = TextAnchor.MiddleCenter,
                fixedHeight = 18,
                fixedWidth = 18,
                padding = new RectOffset(1, 1, 1, 1)
            };

            bool isWarringCanRun = ret.Item1 > 0;
            bool isErrorCanRun = ret.Item2 > 0;
            string warringIcon = isWarringCanRun ? "console.warnicon" : "console.warnicon.inactive.sml";
            string erroricon = isErrorCanRun ? "console.erroricon" : "console.erroricon.inactive.sml";

            if (EditorGUIUtility.isProSkin)
            {
                warringIcon = isWarringCanRun ? "d_console.warnicon" : "d_console.warnicon.inactive.sml";
                erroricon = isErrorCanRun ? "d_console.erroricon" : "d_console.erroricon.inactive.sml";

            }
            GUI.enabled = isWarringCanRun;
            btnRect.y += 2;
            if (GUI.Button(btnRect, DTGUIEx.DTGetContent(icon: warringIcon, tooltip: ret.Item3), style))
            {
                Debug.LogWarning(ret.Item3);
            }
            btnRect.x += 20;
            GUI.enabled = isErrorCanRun;
            if (GUI.Button(btnRect, DTGUIEx.DTGetContent(icon: erroricon, tooltip: ret.Item4), style))
            {
                Debug.LogError(ret.Item4);
            }
            GUI.enabled = true;
            btnRect.y -= 2;
            return btnRect;
        }


        protected void SetBlend()
        {
            int blendMode = (int)material.GetFloat(DTVfxBaseProperty.BlendMode);

            var srcBlendRGB = UnityEngine.Rendering.BlendMode.One;
            var dstBlendRGB = UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha;
            var srcBlendA = UnityEngine.Rendering.BlendMode.One;
            var dstBlendA = UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha;

            // Specific Transparent Mode Settings
            switch (blendMode)
            {
                // srcRGB * srcAlpha + dstRGB * (1 - srcAlpha)
                // preserve spec:
                // srcRGB * (<in shader> ? 1 : srcAlpha) + dstRGB * (1 - srcAlpha)
                case 0://BlendMode.Alpha:
                    srcBlendRGB = UnityEngine.Rendering.BlendMode.SrcAlpha;
                    dstBlendRGB = UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha;
                    srcBlendA = UnityEngine.Rendering.BlendMode.One;
                    dstBlendA = dstBlendRGB;
                    break;
                // srcRGB < srcAlpha, (alpha multiplied in asset)
                // srcRGB * 1 + dstRGB * (1 - srcAlpha)
                case 1://BlendMode.Premultiply:
                    srcBlendRGB = UnityEngine.Rendering.BlendMode.One;
                    dstBlendRGB = UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha;
                    srcBlendA = srcBlendRGB;
                    dstBlendA = dstBlendRGB;
                    break;
                // srcRGB * srcAlpha + dstRGB * 1, (alpha controls amount of addition)
                // preserve spec:
                // srcRGB * (<in shader> ? 1 : srcAlpha) + dstRGB * (1 - srcAlpha)
                case 2://BlendMode.Additive:
                    srcBlendRGB = UnityEngine.Rendering.BlendMode.SrcAlpha;
                    dstBlendRGB = UnityEngine.Rendering.BlendMode.One;
                    srcBlendA = UnityEngine.Rendering.BlendMode.One;
                    dstBlendA = dstBlendRGB;
                    break;
                // srcRGB * 0 + dstRGB * srcRGB
                // in shader alpha controls amount of multiplication, lerp(1, srcRGB, srcAlpha)
                // Multiply affects color only, keep existing alpha.
                case 3://BlendMode.Multiply:
                    srcBlendRGB = UnityEngine.Rendering.BlendMode.DstColor;
                    dstBlendRGB = UnityEngine.Rendering.BlendMode.Zero;
                    srcBlendA = UnityEngine.Rendering.BlendMode.Zero;
                    dstBlendA = UnityEngine.Rendering.BlendMode.One;
                    break;
            }
            if (material.HasProperty(DTVfxBaseProperty.SrcBlend))
                material.SetFloat(DTVfxBaseProperty.SrcBlend, (float)srcBlendRGB);

            if (material.HasProperty(DTVfxBaseProperty.DstBlend))
                material.SetFloat(DTVfxBaseProperty.DstBlend, (float)dstBlendRGB);

            if (material.HasProperty(DTVfxBaseProperty.SrcBlendAlpha))
                material.SetFloat(DTVfxBaseProperty.SrcBlendAlpha, (float)srcBlendA);

            if (material.HasProperty(DTVfxBaseProperty.DstBlendAlpha))
                material.SetFloat(DTVfxBaseProperty.DstBlendAlpha, (float)dstBlendA);
        }
        public void SetUVMate(DTGUIBitDate GUIDate)
        {
            if (GUIDate.GetProp(pKey.matrix0) != null && GUIDate.GetProp(pKey.matrix1) != null)
            {
                (GUIDate.GetProp(pKey.matrix0).vectorValue, GUIDate.GetProp(pKey.matrix1).vectorValue) = DTUtil.SetUVMatr(
                        GUIDate.GetProp(pKey.tex).GetValue().ToVector4(), GUIDate.GetProp(pKey.matrix0).GetValue().ToFloat(ChannelMode.w));
            }
        }

        #endregion
        #region End
        #endregion
    }


}


namespace YF.Art.PostProcessing
{

}